package zozopo.manual.image;


import java.util.Calendar;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;



import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionSupport;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import org.apache.struts2.ServletActionContext;

import zozopo.manual.operations.ContentImagesOS;
import zozopo.manual.operations.ContentImagesTB;
import zozopo.user.operations.UserTB;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;


public class UploadImageBaseAction extends ActionSupport implements Action ,SessionAware,ServletRequestAware,ServletResponseAware{
	
	//基本参数
	private static final int BUFFER_SIZE = 16 * 1024;
	private static final String UPLOAD_PATH = "/manual/content";
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private static final Log log = LogFactory.getLog(LogFactory.class);
	
	private Map<Object, Object> session;
	private HttpServletRequest request;
	private HttpServletResponse response;
	
	
	
	private static final String TEXT_TITLE = "Zozopo.com";

	private static final String WATER_IMG_NAME = "z.png";
	
	private static final String UPLOAD_IMAGES_PATH = "goods";
	
	private static final String UPLOAD_FIRST_IMAGES_PATH = "warehouse";


	// 输入参数:上传过来的文件路径
	private File file;
	private String imageFileName;
	private int imageNumber ;
	private int contentId;
	
	// 输出参数
	private String imageUrl;
	private String smallImageUrl;
	
	private String operationResult;
	
	public String getOperationResult() {
		return operationResult;
	}

	public void setOperationResult(String operationResult) {
		this.operationResult = operationResult;
	}

	
	
	

	public void setServletRequest(HttpServletRequest arg0) {
		// TODO Auto-generated method stub
		request = arg0;
	}

	
	public void setServletResponse(HttpServletResponse arg0) {
		// TODO Auto-generated method stub
		response = arg0;
		//response.setCharacterEncoding("GB2312");
		//response.setContentType("text/xml; charset=gb2312");
	}

	

	public String getImageFileName() {
		return imageFileName;
	}


	public void setSession(Map arg0) {
		// TODO Auto-generated method stub
		session = arg0;
	}
	
	public String execute(){
		
		//权限处理
		UserTB user = (UserTB)session.get("userInfo");
		if(user == null){
			try {
				response.setCharacterEncoding("gb2312");  //这可以使正确提示
				response.getWriter().write("{\"error\":\"用户未登陆\"}");
				response.getWriter().flush();
				response.getWriter().close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}  
			return NONE;
			
		}
		
		ContentImagesTB contentImages;
		
		ContentImagesOS contentImagesOS1 = new ContentImagesOS();
		try{
			contentImages = contentImagesOS1.getByContentId(contentId);
		}finally{
			contentImagesOS1.releaseConnection();
		}
		
		if(contentImages.getUser_id() != user.getId_user()){   //验证content是否为当前用户 Content
			try {
				response.setCharacterEncoding("gb2312");  //这可以使正确提示
				response.getWriter().write("{\"error\":\"用户登陆冲突请刷新后再上传图片\"}");
				response.getWriter().flush();
				response.getWriter().close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}  //返回小图连接
			return NONE;
		}
		
		ContentImagesOS contentImagesOS = new ContentImagesOS();
		try {
			String imageurlJSONInfo = uploadImage();//保存图片
			
			response.getWriter().write(imageurlJSONInfo);  //返回小图连接
			
			response.getWriter().flush();
			response.getWriter().close();
			
			if(contentImagesOS.isExit(contentId)){
				//更新新图片地址
				if(!contentImagesOS.update(contentId, imageNumber, imageUrl, smallImageUrl)){
					throw new Exception();
				} 
			}else{
				//插入新图片地址
				if(!contentImagesOS.insert(contentId,user.getId_user(), imageNumber, imageUrl, smallImageUrl)){
					throw new Exception();
				}
			}
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			contentImagesOS.releaseConnection();
		}
		
		
		return NONE;
	}
	

	
	
	private String getExtention(String fileName) {
		int pos = fileName.lastIndexOf(".");
		return fileName.substring(pos);
	}


	private static void copy(File src, File dist) throws Exception {
		try {
		InputStream in = null;
		OutputStream out = null;
		try {
		in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE);
		out = new BufferedOutputStream(new FileOutputStream(dist), BUFFER_SIZE);

		byte[] buf = new byte[BUFFER_SIZE];
		while (in.read(buf) > 0) {
		out.write(buf);
		}
			out.close();
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
		if (in != null)
		in.close();
		if (out != null)
		out.close();
		}
		} catch (Exception e) {
			e.printStackTrace();
			throw new Exception(e);
		}

	}
	

	public String uploadImage() throws Exception {
		log.debug("[file]--" + file);
		log.debug("[file name]--" + imageFileName);
				
		imageFileName = contentId +""+ imageNumber + getExtention(imageFileName); 
		
		imageFileName =  new Date().getTime() + imageFileName;
		
		//开始处理上传
		String abstractPath = UPLOAD_PATH;
		Calendar calendar =Calendar.getInstance();
		int year = calendar.get(Calendar.YEAR);

		// 得到文件存放路径
		log.debug("[imageFileName]--" + imageFileName);
		String dir = ServletActionContext.getServletContext().getRealPath(UPLOAD_PATH);
		
		File dirs = new File(dir);
		if (!dirs.exists()){
			dirs.mkdir();
		}
		
		//生成年份路径
		dir = dir +"/"+ year;
		abstractPath = abstractPath+"/"+ year;
		
		dirs = new File(dir);
		
		if (!dirs.exists()){
			dirs.mkdir();
		}
		
		//生成目录路径
		dir = dir +"/"+ contentId;
		abstractPath = abstractPath+"/"+ contentId;
		
		dirs = new File(dir);
		
		if (!dirs.exists()){
			dirs.mkdir();
		}
		
		//生成储存图片路径
		dir = dir +"/images";
		abstractPath = abstractPath+"/images";
		
		dirs = new File(dir);
		if (!dirs.exists()){
			dirs.mkdir();
		}
		
		//生成储存小图片路径
		dirs = new File(dir+"/small");
		if (!dirs.exists()){
			dirs.mkdir();
		}
		
		

		// 使用原来的文件名保存图片
		String path = dir + "/" + imageFileName;
		imageUrl = abstractPath+ "/" + imageFileName;
		smallImageUrl = abstractPath + "/small/" + imageFileName;
		
		

		
		File imageFile = new File(path);
		File smallImageFile = new File(dir + "/small/" + imageFileName);
		System.out.println(path);
		copy(file, imageFile);

		// 缩放
		zoom(imageFile,abstractPath + "/small/",imageFileName);
	
		//删除大图
		//imageFile.delete();
		
		// 给大图添加文字水印
		//watermark(imageFile);
		// 给大图添加图片水印，可以是gif或png格式
		//imageWaterMark(imageFile);
		

		// 给小图添加文字水印
		// watermark(sImgpath);
		// 给小图添加图片水印，可以是gif或png格式
		//imageWaterMark(sImgpath);

		
		
	
		
		return "{\"smallImageUrl\":\"" + smallImageUrl + "\",\"imageUrl\":\"" + imageUrl +"\"}";
	}


	public String zoom(File imageFile,String savePath,String fileName) throws Exception {
		String imgType = "jpg";
		log.debug("[zoom][imageFile]--" + imageFile);
		try {

		// 缩略图存放路径
		File todir = new File(ServletActionContext.getServletContext().getRealPath(savePath));
		if (!todir.exists()) {
		todir.mkdir();
		}

		if (!imageFile.isFile())
		throw new Exception(imageFile + " is not image file error in CreateThumbnail!");

		File sImg = new File(todir, imageFileName);
		
		
		if (sImg.getName().toLowerCase().endsWith(".png")) {
			imgType = "PNG";
		}
		ImageIO.setUseCache(true);
		BufferedImage src = ImageIO.read(imageFile);
		
		// 假设图片宽 高 最大为130 80,使用默认缩略算法
		
		
		if ((src.getWidth() > 192)) {
			double width = src.getWidth();			
			double mul = width/192.0;
			
			int iWidth = (int) (src.getWidth()/mul);
			int iHeight = (int) (src.getHeight()/mul);
			
			ScaleFilter sf = new ScaleFilter(iWidth,iHeight);
			
			ImageIO.write(sf.filter(src, null),imgType,sImg);
		}else{   //如果不需要压缩
			copy(imageFile,sImg);
		}
		
		//ImageIO.write((BufferedImage) Itemp, imgType, sImg);

		} catch (IOException e) {
			e.printStackTrace();
			throw new Exception(e);
		}
	
		
		return "";
	}


	public void watermark(File img) throws Exception {
		log.debug("[watermark file name]--" + img.getPath());
		try {

		if (!img.exists()) {
		throw new IllegalArgumentException("file not found!");
		}

		log.debug("[watermark][img]--" + img);

		// 创建一个FileInputStream对象从源图片获取数据流
		FileInputStream sFile = new FileInputStream(img);

		// 创建一个Image对象并以源图片数据流填充
		Image src = ImageIO.read(sFile);

		// 得到源图宽
		int width = src.getWidth(null);
		// 得到源图长
		int height = src.getHeight(null);

		// 创建一个BufferedImage来作为图像操作容器
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		// 创建一个绘图环境来进行绘制图象
		Graphics2D g = image.createGraphics();
		// 将原图像数据流载入这个BufferedImage
		log.debug("width:" + width + " height:" + height);
		g.drawImage(src, 0, 0, width, height, null);
		// 设定文本字体
		//g.setFont(new Font("宋体", Font.BOLD, 28));
		String rand = TEXT_TITLE;
		// 设定文本颜色
		g.setColor(Color.blue);
		// 设置透明度
		g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
		// 向BufferedImage写入文本字符,水印在图片上的坐标
		g.drawString(rand, width - (width - 20), height - (height - 60));
		// 使更改生效
		g.dispose();
		// 创建输出文件流
		FileOutputStream outi = new FileOutputStream(img);
		// 创建JPEG编码对象
		JPEGImageEncoder encodera = JPEGCodec.createJPEGEncoder(outi);
		// 对这个BufferedImage (image)进行JPEG编码
		encodera.encode(image);
		// 关闭输出文件流
		outi.close();
		sFile.close();

		} catch (IOException e) {
		e.printStackTrace();
		throw new Exception(e);
		}
	}


	public void imageWaterMark(File imgFile) throws Exception {
		try {
		// 目标文件
		Image src = ImageIO.read(imgFile);
		int wideth = src.getWidth(null);
		int height = src.getHeight(null);
		
		BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_BGR);
		
		Graphics2D g = image.createGraphics();
		g.drawImage(src, 0, 0, wideth, height, null);

		// 水印文件 路径
		String waterImgPath = ServletActionContext.getServletContext().getRealPath("/"+UPLOAD_FIRST_IMAGES_PATH+"/"+UPLOAD_IMAGES_PATH)+"/"+WATER_IMG_NAME;
		File waterFile = new File(waterImgPath);
		Image waterImg = ImageIO.read(waterFile);

		int w_wideth = waterImg.getWidth(null);
		int w_height = waterImg.getHeight(null);
		//g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
		//g.setComposite(AlphaComposite.Xor);
		
		//g.drawImage(waterImg, (wideth - w_wideth) / 2, (height - w_height) / 2, w_wideth, w_height, null);
		g.drawImage(waterImg, 5 , height-w_height, w_wideth, w_height, null); 
		// 水印文件结束

		g.dispose();
		//*/
		//ImageIO.write(image, "jpg", src);
		FileOutputStream out = new FileOutputStream(imgFile);
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		//JPEGEncodeParam param = new JPEGEncodeParam();
		//param.set
		//encoder.setJPEGEncodeParam()
		encoder.encode(image);
		out.close();
		
		} catch (Exception e) {
		e.printStackTrace();
		}
	}

	public void setFile(File file) {
		this.file = file;
	}


	public void setFileFileName(String fileName) {
		this.imageFileName = fileName;
	}

	public void setImageFileName(String imageFileName) {
		this.imageFileName = imageFileName;
	}


	

	public File getFile() {
		return file;
	}
	
	//删除指定文件夹下所有文件
	//param path 文件夹完整绝对路径
	   public static boolean delAllFile(String path) {
	       boolean flag = false;
	       File file = new File(path);
	       if (!file.exists()) {
	         return flag;
	       }
	       if (!file.isDirectory()) {
	         return flag;
	       }
	       String[] tempList = file.list();
	       File temp = null;
	       for (int i = 0; i < tempList.length; i++) {
	          if (path.endsWith(File.separator)) {
	             temp = new File(path + tempList[i]);
	          } else {
	              temp = new File(path + File.separator + tempList[i]);
	          }
	          if (temp.isFile()) {
	             temp.delete();
	          }
	          if (temp.isDirectory()) {
	             delAllFile(path + "/" + tempList[i]);//先删除文件夹里面的文件
	             delFolder(path + "/" + tempList[i]);//再删除空文件夹
	             flag = true;
	          }
	       }
	       return flag;
	     }
	

	//删除文件夹
	//param folderPath 文件夹完整绝对路径
	
	   public static void delFolder(String folderPath) {
	   try {
	      delAllFile(folderPath); //删除完里面所有内容
	      String filePath = folderPath;
	      filePath = filePath.toString();
	      java.io.File myFilePath = new java.io.File(filePath);
	      myFilePath.delete(); //删除空文件夹
	   } catch (Exception e) {
	     e.printStackTrace(); 
	   }
}

	public String getImageUrl() {
		return imageUrl;
	}

	public void setImageUrl(String imageUrl) {
		this.imageUrl = imageUrl;
	}

	public int getImageNumber() {
		return imageNumber;
	}

	public void setImageNumber(int imageNumber) {
		this.imageNumber = imageNumber;
	}

	public int getContentId() {
		return contentId;
	}

	public void setContentId(int contentId) {
		this.contentId = contentId;
	}

	public String getSmallImageUrl() {
		return smallImageUrl;
	}

	public void setSmallImageUrl(String smallImageUrl) {
		this.smallImageUrl = smallImageUrl;
	}



}
